package speedchina.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import speedchina.dao.user.ResourceMapper;
import speedchina.entity.user.Resource;
import speedchina.entity.user.Role;
import speedchina.entity.user.RoleResource;
import speedchina.entity.user.User;
import speedchina.service.user.ResourceService;
import speedchina.service.user.RoleResourceService;
import speedchina.util.TreeUtils;
import speedchina.util.security.ShiroUtils;

import java.text.MessageFormat;
import java.util.*;

import static speedchina.configuration.shiro.ShiroConfig.PREMISSION_STRING;


@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource>
    implements ResourceService
{
    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private RoleResourceService roleResourceService;

    /**
     * 查询菜单集合
     *
     * @return 所有菜单详情
     */
    @Override
    public List<Resource> selectResouceList(Resource resource)
    {
        return resourceMapper.selectResourceList(resource);
    }

    /**
     * 查询子菜单数量
     *
     * @param parentId 菜单ID
     * @return 结果
     */
    @Override
    public int selectCountResourceByParentId(Long parentId)
    {
        return count(new QueryWrapper<Resource>().eq("parent_id", parentId));
    }

    /**
     * 查询菜单使用数量
     *
     * @param id 菜单ID
     * @return 结果
     */
    @Override
    public int selectCountRoleResourceByResourceId(Long id)
    {
        return roleResourceService.count(
            new QueryWrapper<RoleResource>().eq("resource_id", id));
    }

    /**
     * 删除菜单管理信息
     *
     * @param id 菜单ID
     * @return 结果
     */
    @Override
    public boolean deleteResourceById(Long id)
    {
        ShiroUtils.clearCachedAuthorizationInfo();
//        return remove(new QueryWrapper<Resource>().or("parent_id={0} or id={1}", id, id));
        return remove(new QueryWrapper<Resource>().eq("parent_id",id).or().eq("id",id));
    }

    /**
     * 根据菜单ID查询信息
     *
     * @param id 菜单ID
     * @return 菜单信息
     */
    @Override
    public Resource selectResourceById(Long id)
    {
        return resourceMapper.selectResourceById(id);
    }

    /**
     * 新增保存菜单信息
     *
     * @param resource 菜单信息
     * @return 结果
     */
    @Override
    public boolean insertResource(Resource resource)
    {
        resource.setCreateBy(ShiroUtils.getLoginName());
        ShiroUtils.clearCachedAuthorizationInfo();
        return save(resource);
    }

    /**
     * 根据角色ID查询菜单
     *
     * @param role 角色对象
     * @return 菜单列表
     */
    @Override
    public List<Map<String, Object>> roleResourceTreeData(Role role)
    {
        Long roleId = role.getId();
        List<Map<String, Object>> trees;
        List<Resource> resourceList = list(new QueryWrapper<>());
        if (null != roleId)
        {
            List<String> roleResourceList = resourceMapper.selectResourceTree(roleId);
            trees = getTrees(resourceList, true, roleResourceList, true);
        }
        else
        {
            trees = getTrees(resourceList, false, null, true);
        }
        return trees;
    }

    /**
     * 查询所有菜单
     *
     * @return 菜单列表
     */
    @Override
    public List<Map<String, Object>> resourceTreeData()
    {
        List<Map<String, Object>> trees;
        List<Resource> resourceList = list(new QueryWrapper<>());
        trees = getTrees(resourceList, false, null, false);
        return trees;
    }

    /**
     * 对象转菜单树
     *
     * @param resourceList     菜单列表
     * @param isCheck          是否需要选中
     * @param roleResourceList 角色已存在菜单列表
     * @param permsFlag        是否需要显示权限标识
     * @return
     */
    public List<Map<String, Object>> getTrees(List<Resource> resourceList, boolean isCheck,
                                              List<String> roleResourceList,
                                              boolean permsFlag)
    {
        List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        for (Resource resource : resourceList)
        {
            Map<String, Object> deptMap = new HashMap<String, Object>();
            deptMap.put("id", resource.getId().toString());
            deptMap.put("pId", resource.getParentId().toString());
            deptMap.put("name", transResourceName(resource, roleResourceList, permsFlag));
            deptMap.put("title", resource.getResourceName());
            if (isCheck)
            {
                deptMap.put("checked",
                    roleResourceList.contains(resource.getId() + resource.getPerms()));
            }
            else
            {
                deptMap.put("checked", false);
            }
            trees.add(deptMap);
        }
        return trees;
    }

    public String transResourceName(Resource resource, List<String> roleResourceList,
                                    boolean permsFlag)
    {
        StringBuffer sb = new StringBuffer();
        sb.append(resource.getResourceName());
        if (permsFlag)
        {
            sb.append("<font color=\"#888\">&nbsp;&nbsp;&nbsp;" + resource.getPerms() + "</font>");
        }
        return sb.toString();
    }

    /**
     * 根据用户查询菜单
     *
     * @param user 用户信息
     * @return 菜单列表
     */
    @Override
    public List<Resource> selectResourcesByUser(User user)
    {
        List<Resource> resources;
        // 管理员显示所有菜单信息
        if (user.isAdmin())
        {
            resources = resourceMapper.selectResourceNormalAll();
        }
        else
        {
            resources = resourceMapper.selectResourcesByUserId(user.getId());
        }
        return TreeUtils.getChildPerms(resources, 0);
    }

    @Override
    public Set<String> selectPermsByUserId(Long userId)
    {
        List<String> perms = resourceMapper.selectPermsByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms)
        {
            if (StringUtils.isNotEmpty(perm))
            {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    public List<Resource> selectParentResource()
    {
        return resourceMapper.selectParentResource();
    }

    /**
     * 获取所有菜单类型
     *
     * @return
     */
    @Override
    public List<String> selectResourceType()
    {
        return resourceMapper.selectResourceType();
    }

    @Override
    public Long selectIdByName(String resourceName)
    {
        return resourceMapper.selectIdByName(resourceName);
    }

    @Override
    public List<Map<String, Object>> roleMenuTreeData(Role role)
    {
        Long roleId = role.getId();
        List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        List<Resource> menuList = list(new QueryWrapper<Resource>().eq("visible",0)
        );
        if (roleId != null)
        {
            List<String> roleMenuList = resourceMapper.selectMenuTree(roleId);
            trees = getTrees(menuList, true, roleMenuList, true);
        }
        else
        {
            trees = getTrees(menuList, false, null, true);
        }
        return trees;
    }

    @Override
    public Map<String, String> selectPermsAll()
    {
        LinkedHashMap<String, String> section = new LinkedHashMap<>();
        List<Resource> permissions = list(new QueryWrapper<>());
        if (!permissions.isEmpty())
        {
            for (Resource menu : permissions)
            {
                section.put(menu.getUrl(), MessageFormat.format(PREMISSION_STRING, menu.getPerms()));
            }
        }
        return section;
    }
}